package top.zhangjianyong.tools.indicator.strategy.impl;

import org.springframework.stereotype.Component;
import top.zhangjianyong.tools.entity.ETFData;
import top.zhangjianyong.tools.indicator.context.IndicatorContext;
import top.zhangjianyong.tools.indicator.model.TechnicalIndicatorResult;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 成交量指标计算器
 * 计算原始成交量、20日均量、成交量比率（vol_ratio）
 *
 * @author zhangjianyong
 * @date 2024/01/01
 */
@Component
public class VolumeIndicator extends AbstractIndicator {

    private static final String INDICATOR_NAME = "VOLUME";
    private static final int PERIOD = 20;

    @Override
    public String getName() {
        return INDICATOR_NAME;
    }

    @Override
    public int getMinDataSize() {
        return PERIOD;
    }

    @Override
    protected TechnicalIndicatorResult doCalculate(IndicatorContext context) {
        List<ETFData> dataList = context.getDataList();

        if (dataList.isEmpty()) {
            return TechnicalIndicatorResult.failure(getName(), "数据列表为空");
        }

        // 当前成交量
        ETFData currentData = dataList.get(dataList.size() - 1);
        Long currentVolume = currentData.getVolume() != null ? currentData.getVolume() : 0L;

        // 计算20日均量
        BigDecimal avgVolume = calculateAverageVolume(dataList);

        // 计算成交量比率（vol_ratio = 当前成交量 / 20日均量）
        BigDecimal volRatio = BigDecimal.ZERO;
        if (avgVolume.compareTo(BigDecimal.ZERO) != 0) {
            volRatio = BigDecimal.valueOf(currentVolume)
                .divide(avgVolume, 4, RoundingMode.HALF_UP);
        } else {
            volRatio = BigDecimal.ONE; // 如果均量为0，比率设为1
        }

        TechnicalIndicatorResult result = TechnicalIndicatorResult.success(getName());
        result.addValue("volume", BigDecimal.valueOf(currentVolume));
        result.addValue("volume_avg_20", avgVolume);
        result.addValue("vol_ratio", volRatio.setScale(2, RoundingMode.HALF_UP));

        return result;
    }

    /**
     * 计算20日平均成交量
     */
    private BigDecimal calculateAverageVolume(List<ETFData> dataList) {
        if (dataList.size() < PERIOD) {
            return BigDecimal.ZERO;
        }

        // 取最后PERIOD个数据点
        List<ETFData> subList = dataList.subList(dataList.size() - PERIOD, dataList.size());

        BigDecimal sum = BigDecimal.ZERO;
        int count = 0;

        for (ETFData data : subList) {
            if (data.getVolume() != null) {
                sum = sum.add(BigDecimal.valueOf(data.getVolume()));
                count++;
            }
        }

        if (count == 0) {
            return BigDecimal.ZERO;
        }

        return sum.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP);
    }
}
